package com.ruoyi.framework.web.service

import com.ruoyi.common.constant.Constants
import com.ruoyi.common.utils.MyStringUtils
import com.ruoyi.common.utils.SecurityUtils.loginUser
import com.ruoyi.framework.security.context.PermissionContextHolder
import org.springframework.stereotype.Service
import org.springframework.util.CollectionUtils

/**
 * RuoYi首创 自定义权限实现，ss取自SpringSecurity首字母
 *
 * @author ruoyi
 */
@Service("ss")
class PermissionService {
    /**
     * 验证用户是否具备某权限
     *
     * @param permission 权限字符串
     * @return 用户是否具备某权限
     */
    fun hasPermi(permission: String?): Boolean {
        if (MyStringUtils.isEmpty(permission)) {
            return false
        }
        val loginUser = loginUser
        if (MyStringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.permissions)) {
            return false
        }
        PermissionContextHolder.context = permission
        return hasPermissions(loginUser.permissions, permission)
    }

    /**
     * 验证用户是否不具备某权限，与 hasPermi逻辑相反
     *
     * @param permission 权限字符串
     * @return 用户是否不具备某权限
     */
    fun lacksPermi(permission: String?): Boolean {
        return !hasPermi(permission)
    }

    /**
     * 验证用户是否具有以下任意一个权限
     *
     * @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
     * @return 用户是否具有以下任意一个权限
     */
    fun hasAnyPermi(permissions: String): Boolean {
        if (MyStringUtils.isEmpty(permissions)) {
            return false
        }
        val loginUser = loginUser
        if (MyStringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.permissions)) {
            return false
        }
        PermissionContextHolder.context = permissions
        val authorities = loginUser.permissions
        for (permission in permissions.split(Constants.PERMISSION_DELIMETER.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
            if (hasPermissions(authorities, permission)) {
                return true
            }
        }
        return false
    }

    /**
     * 判断用户是否拥有某个角色
     *
     * @param role 角色字符串
     * @return 用户是否具备某角色
     */
    fun hasRole(role: String?): Boolean {
        if (MyStringUtils.isEmpty(role)) {
            return false
        }
        val loginUser = loginUser
        if (MyStringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.user!!.roles)) {
            return false
        }
        for (sysRole in loginUser.user!!.roles!!) {
            val roleKey = sysRole.roleKey
            if (Constants.SUPER_ADMIN == roleKey || roleKey == MyStringUtils.myTrim(role)) {
                return true
            }
        }
        return false
    }

    /**
     * 验证用户是否不具备某角色，与 isRole逻辑相反。
     *
     * @param role 角色名称
     * @return 用户是否不具备某角色
     */
    fun lacksRole(role: String?): Boolean {
        return !hasRole(role)
    }

    /**
     * 验证用户是否具有以下任意一个角色
     *
     * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
     * @return 用户是否具有以下任意一个角色
     */
    fun hasAnyRoles(roles: String): Boolean {
        if (MyStringUtils.isEmpty(roles)) {
            return false
        }
        val loginUser = loginUser
        if (MyStringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.user!!.roles)) {
            return false
        }
        for (role in roles.split(Constants.ROLE_DELIMETER.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
            if (hasRole(role)) {
                return true
            }
        }
        return false
    }

    /**
     * 判断是否包含权限
     *
     * @param permissions 权限列表
     * @param permission 权限字符串
     * @return 用户是否具备某权限
     */
    private fun hasPermissions(permissions: Set<String>?, permission: String?): Boolean {
        return permissions!!.contains(Constants.ALL_PERMISSION) || permissions.contains(MyStringUtils.myTrim(permission))
    }
}
